package com.xoomworks.rsfr.core.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.xoomworks.rsfr.core.service.BaseService;
import com.xoomworks.rsfr.model.BaseEntity;

public class BaseServiceImpl<T extends BaseEntity> implements BaseService<T> {

    private Class<T> clazz;
    public static final String BASE_URL = "http://localhost:8080/RS/";
    public Class<T[]> clazzArray;

    public String entityUri;

    @Autowired
    public RestTemplate restTemplate;

    public void setEntityUri(final String entityUri) {
        this.entityUri = entityUri;
    }

    public void setClazz(final Class<T> clazzToSet) {
        this.clazz = clazzToSet;
    }

    public void setClazzArray(final Class<T[]> clazzToSet) {
        this.clazzArray = clazzToSet;
    }

    @Override
    public T find(final Long id) {
        HttpHeaders headers = new HttpHeaders();
        AuthenticationServiceImpl.setAuthenticationHeader(headers);
        HttpEntity<T> requestEntity = new HttpEntity<T>(null, headers);

        ResponseEntity<T> returnedEntity = restTemplate.exchange(BASE_URL + entityUri + "/Get/"
                + id, HttpMethod.GET, requestEntity, clazz);
        return returnedEntity.getBody();
    }

    @Override
    public List<T> findAll() {
        HttpHeaders headers = new HttpHeaders();
        AuthenticationServiceImpl.setAuthenticationHeader(headers);
        HttpEntity<T> requestEntity = new HttpEntity<T>(null, headers);

        List<T> resultList = new ArrayList<T>();
        T[] entities = null;
        try {
            ResponseEntity<T[]> returnedEntity = restTemplate.exchange(BASE_URL + entityUri
                    + "/Get", HttpMethod.GET, requestEntity, clazzArray);
            entities = returnedEntity.getBody();
        } catch (RestClientException e) {
            e.printStackTrace();
        }

        for (T entity : entities) {
            resultList.add(entity);
        }
        return resultList;
    }

    @Override
    public Long save(final T entity) {
        HttpHeaders headers = new HttpHeaders();
        AuthenticationServiceImpl.setAuthenticationHeader(headers);
        HttpEntity<T> requestEntity = new HttpEntity<T>(entity, headers);

        ResponseEntity<T> returnedEntity = restTemplate.exchange(BASE_URL + entityUri
                + "/Add", HttpMethod.POST, requestEntity, clazz);

        return returnedEntity.getBody().getId();
    }

    @Override
    public void update(final T entity) {
        HttpHeaders headers = new HttpHeaders();
        AuthenticationServiceImpl.setAuthenticationHeader(headers);
        HttpEntity<T> requestEntity = new HttpEntity<T>(entity, headers);

        restTemplate.exchange(BASE_URL + entityUri + "/Update/" + entity.getId(),
                HttpMethod.PUT, requestEntity, clazz);

    }

    @Override
    public void deleteById(final Long id) {
        HttpHeaders headers = new HttpHeaders();
        AuthenticationServiceImpl.setAuthenticationHeader(headers);
        HttpEntity<T> requestEntity = new HttpEntity<T>(null, headers);

        restTemplate.exchange(BASE_URL + entityUri
                + "/Delete/" + id, HttpMethod.DELETE, requestEntity, clazz);

    }

}
